package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.heima.article.dto.ArticleStreamMessage;
import com.heima.article.entity.ApArticle;
import com.heima.article.entity.ArticleCache;
import com.heima.article.service.IApArticleService;
import com.heima.article.service.IHotArticleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class HotArticleServiceImpl implements IHotArticleService {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private IApArticleService apArticleService;


    @Override
    public void compute() {
        System.out.println("开始计算文章热点数据分值"+new Date());
        //查询从当天0点0分0秒往前推5天的所有文章
        Date now=new Date();
        Date to=new Date(now.getYear(),now.getMonth(),now.getDate());
        Date from=new Date(to.getTime()-5*24*60*60*1000);
        LambdaQueryWrapper<ApArticle> query=new LambdaQueryWrapper<>();
        query.eq(ApArticle::getIsDelete,false);
        query.eq(ApArticle::getIsDown,false);
        query.lt(ApArticle::getPublishTime,to);
        query.gt(ApArticle::getPublishTime,from);
        List<ApArticle> articles = apArticleService.list(query);
        for (ApArticle article : articles) {
            Double score=computeScore(article);
            System.out.println("文章"+article.getId()+":"+article.getTitle()+"分值为："+score);
            ArticleCache cache=new ArticleCache();
            BeanUtils.copyProperties(article,cache);
            String key="hot_article_first_page_0";
            String value= JSON.toJSONString(cache);
            redisTemplate.opsForZSet().add(key,value,score);
            String channelKey="hot_article_first_page_"+article.getChannelId();
            redisTemplate.opsForZSet().add(channelKey,value,score);
            //设置过期时间
            redisTemplate.expire(key,23*60+59, TimeUnit.MINUTES);
            redisTemplate.expire(channelKey,23*60+59, TimeUnit.MINUTES);
        }

    }

    @Override
    public void update(ArticleStreamMessage message) {
        //根据文章id查询文章
        ApArticle article = apArticleService.getById(message.getArticleId());
        ArticleCache articleCache=new ArticleCache();
        BeanUtils.copyProperties(article,articleCache);
        //计算本次聚合的分值，当日操作的权重在原来的基础上*3
       double scorePlus= computeScore(message);
       //判断redis中是否有该文章的数据
        String key="hot_article_first_page"+article.getChannelId();
        String value=JSON.toJSONString(articleCache);
        Double score = redisTemplate.opsForZSet().score(key, value);
        if(score!=null){
            redisTemplate.opsForZSet().incrementScore(key,value,scorePlus);
        }else{
            Double computeScore = computeScore(article);
            double totalScore=scorePlus+computeScore;
            redisTemplate.opsForZSet().add(key,value,totalScore);
            redisTemplate.opsForZSet().add("hot_article_first_page_0",value,totalScore);
            //设置过期时间
            redisTemplate.expire(key,23*60+59, TimeUnit.MINUTES);
            redisTemplate.expire("hot_article_first_page_0",23*60+59, TimeUnit.MINUTES);

        }
        LambdaUpdateWrapper<ApArticle> update=new LambdaUpdateWrapper<>();
        update.eq(ApArticle::getId,message.getArticleId());
        update.setSql("views=views+"+message.getView());
        update.setSql("likes=likes+"+message.getLike());
        update.setSql("comment=comment+"+message.getComment());
        update.setSql("collection=collection+"+message.getCollect());
        apArticleService.update(update);
    }

    private double computeScore(ArticleStreamMessage message) {
        double scorePlus=0;
            scorePlus+=message.getView()*1*3;
            scorePlus+=message.getLike()*3*3;
            scorePlus+=message.getComment()*5*3;
            scorePlus+=message.getCollect()*8*3;
        return scorePlus;
    }

    private Double computeScore(ApArticle article) {
        double score=0;
        if(article.getViews()!=null){
            score+=article.getViews()* 1;
        }
        if(article.getLikes()!=null){
            score+=article.getLikes()*3;
        }
        if(article.getComment()!=null){
            score+=article.getComment()*5;
        }
        if(article.getCollection()!=null){
            score+=article.getCollection()*8;
        }
        return score;
    }
}
